package com.eshop.we.utils;

import com.aliyun.oss.OSSClient;
import com.aliyun.oss.model.*;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.net.URL;
import java.util.Date;
import java.util.Random;

/**
 * 阿里云 OSS文件类
 * 
 * @author YuanDuDu
 */
public class OSSClientUtil {

	Log log = LogFactory.getLog(OSSClientUtil.class);
	// endpoint以杭州为例，其它region请按实际情况填写 endpoint：oss-cn-beijing.aliyuncs.com
	private static String endpoint = "oss-cn-beijing.aliyuncs.com";
	// accessKey
	private static String accessKeyId = "";
	private static String accessKeySecret = "";
	// 空间
	private static String bucketName = "qqtlhnc";
	// 文件存储目录
	private  static  String filedir = "images/";

	private OSSClient ossClient;

	public OSSClientUtil() {
		ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
	}

	/**
	 * 初始化
	 */
	public void init() {
		ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
	}
	 //images/1529250470026.jpeg images/35651529250875352.jpeg
	public static void main(String[] args) {
		OSSClientUtil oss = new OSSClientUtil();
		File file = new File("D:\\bat.JPEG");
	String key = oss.uploadImg2Oss(file);
		System.out.println(key);
	String url = oss.getImgUrl(key);
	System.out.println(url);

		// 构造ListObjectsRequest请求。
		ListObjectsRequest listObjectsRequest = new ListObjectsRequest(bucketName);
// "/" 为文件夹的分隔符。
		listObjectsRequest.setDelimiter("/");
// 列出fun目录下的所有文件和文件夹。
		listObjectsRequest.setPrefix("images/");
		OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret);
		ObjectListing listing = ossClient.listObjects(listObjectsRequest);
// 遍历所有Object。
		System.out.println("Objects:");
//ObjectSummaries 的列表中给出的是fun目录下的文件。
		for (OSSObjectSummary objectSummary : listing.getObjectSummaries()) {
			System.out.println(objectSummary.getKey());
		}
// 遍历所有CommonPrefix。
		System.out.println("\nimages:");
//CommonPrefixs列表中给出的是fun目录下的所有子文件夹。fun/movie/001.avi 和 fun/movie/007.avi 两个文件并没有被列出来，因为它们属于fun文件夹下的movie目录。
		for (String commonPrefix : listing.getCommonPrefixes()) {
			System.out.println(commonPrefix);
		}
	}
	
	/**
	 * 销毁
	 */
	public void destory() {
		ossClient.shutdown();
	}

	/**
	 * 上传图片
	 * 
	 * @param url
	 */
	public void uploadImg2Oss(String url) {
		File fileOnServer = new File(url);
		FileInputStream fin;
		try {
			fin = new FileInputStream(fileOnServer);
			String[] split = url.split("/");
			this.uploadFile2OSS(fin, split[split.length - 1]);
		} catch (FileNotFoundException e) {
			e.printStackTrace();
		}
	}

	public String uploadImg2Oss(File file) {
		
		String originalFilename = file.getName();
		String substring = originalFilename.substring(
				originalFilename.lastIndexOf(".")).toLowerCase();
		Random random = new Random();
		String name = filedir+random.nextInt(10000) + System.currentTimeMillis()
				+ substring;
		try {
			InputStream inputStream = new FileInputStream(file);
			this.uploadFile2OSS(inputStream, name);
			return name;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return name;
	}
	
	public String uploadImg2Oss(MultipartFile file) {
		String originalFilename = file.getOriginalFilename();
		System.out.println(originalFilename);  
		String substring = originalFilename.substring(
				originalFilename.lastIndexOf(".")).toLowerCase();
		Random random = new Random();
		String name = filedir+random.nextInt(10000) + System.currentTimeMillis()
				+ substring;
		try {
			this.uploadFile2OSS(file.getInputStream(), name);
			return name;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return name;
	}

	/**
	 * 获得图片路径
	 * 
	 * @param fileUrl
	 * @return
	 */
	public String getImgUrl(String fileUrl) {
		if (!StringUtils.isEmpty(fileUrl)) {
			String[] split = fileUrl.split("/");
			return this.getUrl(filedir + split[split.length - 1]);
		}
		return null;
	}

	/**
	 * 上传到OSS服务器 如果同名文件会覆盖服务器上的
	 * 
	 * @param instream
	 *            文件流
	 * @param fileName
	 *            文件名称 包括后缀名
	 * @return 出错返回"" ,唯一MD5数字签名
	 */
	public String uploadFile2OSS(InputStream instream, String fileName) {
		String ret = "";
		try {
			// 创建上传Object的Metadata
			ObjectMetadata objectMetadata = new ObjectMetadata();
			objectMetadata.setContentLength(instream.available());
			objectMetadata.setCacheControl("public");  
//			objectMetadata.setHeader("Pragma", "no-cache");
			objectMetadata.setContentType(getcontentType(fileName
					.substring(fileName.lastIndexOf("."))));
			objectMetadata.setContentDisposition("inline;filename=" + fileName);
			// 上传文件
			PutObjectResult putResult = ossClient.putObject(bucketName, ""
					+ fileName, instream, objectMetadata);
			ret = putResult.getETag();
		} catch (IOException e) {
			log.error(e.getMessage(), e);
		} finally {
			try {
				if (instream != null) {
					instream.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return ret;
	}

	/**
	 * Description: 判断OSS服务文件上传时文件的contentType
	 * 
	 * @param FilenameExtension
	 *            文件后缀
	 * @return String
	 */
	public static String getcontentType(String FilenameExtension) {
		if (FilenameExtension.equalsIgnoreCase("bmp")) {
			return "image/bmp";
		}
		if (FilenameExtension.equalsIgnoreCase("gif")) {
			return "image/gif";
		}
		if (FilenameExtension.equalsIgnoreCase("jpeg")
				|| FilenameExtension.equalsIgnoreCase("jpg")
				|| FilenameExtension.equalsIgnoreCase("png")) {
			return "image/jpeg";
		}
		if (FilenameExtension.equalsIgnoreCase("html")) {
			return "text/html";
		}
		if (FilenameExtension.equalsIgnoreCase("txt")) {
			return "text/plain";
		}
		if (FilenameExtension.equalsIgnoreCase("vsd")) {
			return "application/vnd.visio";
		}
		if (FilenameExtension.equalsIgnoreCase("pptx")
				|| FilenameExtension.equalsIgnoreCase("ppt")) {
			return "application/vnd.ms-powerpoint";
		}
		if (FilenameExtension.equalsIgnoreCase("docx")
				|| FilenameExtension.equalsIgnoreCase("doc")) {
			return "application/msword";
		}
		if (FilenameExtension.equalsIgnoreCase("xml")) {
			return "text/xml";
		}
		return "image/jpeg";
	}

	/**
	 * 获得url链接
	 * 
	 * @param key
	 * @return
	 */
	public String getUrl(String key) {
		// 设置URL过期时间为10年 3600l* 1000*24*365*10
		Date expiration = new Date(new Date().getTime() + 3600l * 1000 * 24
				* 365 * 10);
		// 生成URL
		URL url = ossClient.generatePresignedUrl(bucketName, key, expiration);
		if (url != null) {
			return url.toString();
		}
		return null;
	}
	
	/**
	 * 拷贝文件
	 * 
	 */
	public void copyImg2Oss(String key) {
		// 创建CopyObjectRequest对象
		CopyObjectRequest copyObjectRequest = new CopyObjectRequest(bucketName, key, bucketName, key);
		// 设置新的Metadata
		ObjectMetadata objectMetadata = new ObjectMetadata();
		objectMetadata.setCacheControl("public");  
		copyObjectRequest.setNewObjectMetadata(objectMetadata);
		// 复制Object
		CopyObjectResult result = ossClient.copyObject(copyObjectRequest);
		System.out.println("ETag: " + result.getETag() + " LastModified: " + result.getLastModified());
		
	}
	
	
	/**
	 * 删除
	 * 
	 * @param
	 */
	public void delImg2Oss(String key) {
		// 删除Object
		ossClient.deleteObject(bucketName, key);
		
	}
	
	/**
	 * 查询
	 * 
	 * @param
	 */
	public ObjectListing listObjectsMaxKey(int maxKeys) {
		ObjectListing  list = ossClient.listObjects(new ListObjectsRequest(bucketName).withMaxKeys(maxKeys));
		return list;
	}
	
	/**
	 * 查询
	 * 
	 * @param
	 */
	public ObjectListing listObjects(String nextMarker,int maxKeys) {
		ObjectListing  list =  ossClient.listObjects(new ListObjectsRequest(bucketName).withMarker(nextMarker).withMaxKeys(maxKeys));
		return list;
	}


	/**
	 * 获取object,并读取流输出至OutputStream<br>
	 * 用于流式下载
	 *
	 * @author kira
	 * @param
	 * @param key
	 * @param
	 * @throws IOException
	 */
	public  byte[] getObjectToOutputStream(String key) throws IOException {
		System.out.print(endpoint + "获取Object,输出至OutputStream,bucketName=" + bucketName + ",key=" + key);
		byte[] buf = new byte[1024];
		InputStream in = ossClient.getObject(bucketName, key).getObjectContent();
		int length = 0;
		ByteArrayOutputStream swapStream = new ByteArrayOutputStream();
		while ((length = in.read(buf)) > 0) {
			//out.write(buf, 0, length);
			swapStream.write(buf, 0, length);
		}
		byte[] in2b = swapStream.toByteArray();
		in.close();
	//	out.close();
		return in2b;
	}
}